package cn.edu.stu.syllabus.oa.detail;

import android.text.TextUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import cn.edu.stu.syllabus.datas.RequestState;
import cn.edu.stu.syllabus.di.scope.FragmentScoped;
import cn.edu.stu.syllabus.repository.oa.OaStarDataRepository;
import cn.edu.stu.syllabus.repository.oa.local.OaInfoEntry;
import cn.edu.stu.syllabus.repository.oaFile.OaFileDataRepository;
import cn.edu.stu.syllabus.repository.oaFile.local.OaFileEntry;
import cn.edu.stu.syllabus.utils.ExtraNameJoiner;
import cn.edu.stu.syllabus.utils.ListUtils;
import cn.edu.stu.syllabus.utils.RxSchedulerUtils;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Action1;
import rx.subscriptions.CompositeSubscription;

import static cn.edu.stu.syllabus.utils.NullPointerUtils.checkNotNull;

/**
 * Created by daidaijie on 2017/3/18.
 */

@FragmentScoped
public class OaDetailPresenter implements OaDetailContract.Presenter {

    private final OaDetailContract.View mView;

    private final OaInfoEntry mOaInfoEntry;

    private final OaStarDataRepository mOaStarDataRepository;

    private final CompositeSubscription mCompositeSubscription;

    private final OaFileDataRepository mOaFileDataRepository;

    private String mContent;

    private List<OaFileEntry> mOaFileEntries;

    private static final String EXTRA_OA_FILE_ENTRY = ExtraNameJoiner.join(
            OaDetailPresenter.class, "mOaFileEntries"
    );

    private static final String EXTRA_CONTENT = ExtraNameJoiner.join(
            OaDetailPresenter.class, "mContent"
    );

    private static final String EXTRA_REQUEST_STATE = ExtraNameJoiner.join(
            OaDetailPresenter.class, "mRequestState"
    );

    private int mRequestState;

    @Inject
    public OaDetailPresenter(OaDetailContract.View view,
                             OaInfoEntry oaInfoEntry,
                             OaStarDataRepository oaStarDataRepository,
                             OaFileDataRepository oaFileDataRepository) {
        mView = checkNotNull(view);
        mOaInfoEntry = checkNotNull(oaInfoEntry);
        mOaStarDataRepository = checkNotNull(oaStarDataRepository);
        mOaFileDataRepository = checkNotNull(oaFileDataRepository);
        mCompositeSubscription = new CompositeSubscription();
    }

    @Inject
    public void setupListeners() {
        mView.setPresenter(this);
    }

    @Override
    public void subscribe() {
        if (TextUtils.isEmpty(mContent)) {
            showContent();
        }
        if (mOaInfoEntry.getMAccessFileCount() > 0) {
            if (mOaFileEntries != null) {
                mView.showOaFiles(mOaFileEntries);
                mView.setOaFilesHeader(true);
            } else {
                if (RequestState.isError(mRequestState)) {
                    mView.showLoadingError();
                } else {
                    loadOaFiles();
                }
            }
        }
    }

    private void showContent() {
        Subscription subscription = Observable.just(mOaInfoEntry.getHtmlContentAfterFormatter())
                .compose(RxSchedulerUtils.<String>computation2mainSchedulersTransformer())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String content) {
                        mView.showOaInfoContent(content);
                    }
                });
        mCompositeSubscription.add(subscription);
    }

    @Override
    public void unsubscribe() {
        mCompositeSubscription.unsubscribe();
    }

    @Override
    public void starOaInfo() {
        mOaStarDataRepository.starOaInfoEntry(mOaInfoEntry);
    }

    @Override
    public void unstarOaInfo() {
        mOaStarDataRepository.unstarOaInfoEntry(mOaInfoEntry);
    }

    @Override
    public void loadOaFiles() {

        mRequestState = RequestState.REQUEST_FIRST;

        Subscription subscription = mOaFileDataRepository.getOaFileEntry(mOaInfoEntry.getMRemoteId())
                .compose(RxSchedulerUtils.<List<OaFileEntry>>io2mainSchedulersTransformer())
                .subscribe(new Subscriber<List<OaFileEntry>>() {

                    @Override
                    public void onStart() {
                        mView.showLoading();
                    }

                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        mRequestState = RequestState.REQUEST_ERROR;
                        mView.showLoadingError();
                    }

                    @Override
                    public void onNext(List<OaFileEntry> oaFileEntries) {
                        if (ListUtils.getListSizeSafety(oaFileEntries) > 0) {
                            mView.showOaFiles(oaFileEntries);
                            mView.setOaFilesHeader(true);
                            mRequestState = RequestState.REQUEST_SUCCESS;
                            mOaFileEntries = oaFileEntries;
                        } else {
                            mView.setOaFilesHeader(false);
                        }
                    }
                });

        mCompositeSubscription.add(subscription);
    }

    @Override
    public boolean isStarOaInfo() {
        return mOaStarDataRepository.isExistEntry(mOaInfoEntry);
    }

    @Override
    public Map<String, Object> getStoreData() {
        Map<String, Object> storeData = new HashMap<>();
        storeData.put(EXTRA_OA_FILE_ENTRY, mOaFileEntries);
        storeData.put(EXTRA_CONTENT, mContent);
        storeData.put(EXTRA_REQUEST_STATE, mRequestState);
        return storeData;
    }

    @Override
    public void restoreData(Map<String, Object> storeData) {
        mOaFileEntries = (List<OaFileEntry>) storeData.get(EXTRA_OA_FILE_ENTRY);
        mContent = (String) storeData.get(EXTRA_CONTENT);
        mRequestState = (int) storeData.get(EXTRA_REQUEST_STATE);
    }
}
